/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: WirelessServer.hpp,v 1.3 2009-05-13 07:18:19 amaula Exp $
 *
 * \file
 * \brief MaCI - Wireless Server interface header.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#ifndef _MACI_INTERFACE_WIRELESSSERVER_HPP_
#define _MACI_INTERFACE_WIRELESSSERVER_HPP_
#include "MaCI.hpp"
#include "WirelessData.hpp"
#include "sync.hpp"
#include "thread.hpp"
#include <list>


// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
  class GIMIMessage;
}

namespace MaCI {
  namespace Wireless {

    /** MaCI - Wireless Server interface
     * 
     * This class contains the methods and types for providing
     * the Wireless service in the GIMnet.
     */
    class CWirelessServer : public MaCI::CMaCI
                         // ,private gim::CSync,
                         // private gim::CThread
    {
    public:
      /** Constructor.
       * 
       * Constructor of the WirelessServer. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aMaCICtrlServerPtr Pointer to GIMI used for communication
       * @param[in] aInterfaceMinor Interface minor number. Usually
       * used to indicate the instance of devices of same type.
       * @param[in] aDescription User provided description about
       * service. This description will be appended after text
       * 'MaCI-WirelessServer; ' in the GIMI service description
       * field.
       * @param[in] aInstanceName Specify Instance name here.
       */
      CWirelessServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, 
                   const int aInterfaceMinor,
                   const std::string &aDescription = "",
                   const std::string &aInstanceName = "");


      /** Destructor.
       */
      ~CWirelessServer();
 

      /** Send WirelessData element
       *
       * This function sends an WirelessData container to service
       * subscribers.\n
       *
       * The container to send must contain atleast the following
       * elements:\n
       * \li \c TTimestamp
       * \li \c TWirelessEvent
       *
       * @param[in] aWirelessData   CWirelessData container containing data to send.
       * @return                 Returns a value of type MaCI::EMaCIError.
       */
      MaCI::EMaCIError SendWirelessEvent(const CWirelessData &aWirelessData);

      
      /** Return next incoming command in Queue.
       *
       * This function waits for new commands to arrive for a maximum
       * of 'aTimeout_ms' milliseconds. If a command is received, it
       * is stored to reference 'aData', and the function will return
       * KMaCIOK.
       *
       * @param[out] aData      Reference to CWirelessData to be filled with
       *                        received information.
       * @param[in] aTimeout_ms Timeout in milliseconds to sleep waiting
       *                        for the operation to complete. If this
       *                        timeout exceeds and no commands are
       *                        received, this function returns KMaCITimeout.
       *
       * @return                \c 'KMaCIOK' on succesfully received command.\n
       *                        \c 'KMaCITimeout' if timeout value exceeded.\n
       *                        \c 'KMaCIInvalidFormat' if the client received
       *                        a message of invalid format. It is safe to ignore this,
       *                        as it is only a notification for the application
       *                        that an invalid message was received. The event
       *                        is returned as it may help tracing down some
       *                        implementation problems.
       */
      MaCI::EMaCIError WaitCommand(CWirelessData &aData, 
                                   const unsigned int aTimeout_ms);

      
    protected:
      /** Open device.
       *
       * Opens the device, basicly registers device to GIMI.
       *  
       * @return                Returns a value of type MaCI::EMaCIError. 
       *                        
       * \see EMaCIError
       */
      MaCI::EMaCIError DoOpen(void);
      
      
      /** Close device.
       *
       * Closes the device. Closes all GIMI registrations and queues.
       *
       * @return                Returns a value of type EMaCIError.
       *
       * \see EMaCIError
       */
      MaCI::EMaCIError DoClose(void);

    private:
      //      int ThreadFunction(const int aThreadNumber); ///< Incoming data handler function
      //      int ProcessMessage(const gimi::GIMIMessage &msg); ///< Incoming data processor function
      bool iServerActive; ///< Is the server active? - flag
      std::string iServiceDescription; ///< User provided service description field.
      unsigned int iWirelessSequenceNumber;
    };

  }
}


#endif //_MACI_INTERFACE_WIRELESSSERVER_HPP_
